package com.huiying.service.Impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import com.huiying.constant.MessageConstant;
import com.huiying.context.BaseContext;
import com.huiying.entity.dto.UserDTO;
import com.huiying.entity.entity.Follow;
import com.huiying.entity.entity.User;
import com.huiying.entity.vo.FollowVO;
import com.huiying.entity.vo.UserVO;
import com.huiying.mapper.DemandMapper;
import com.huiying.mapper.FollowMapper;
import com.huiying.mapper.UserMapper;
import com.huiying.mapper.WorkMapper;
import com.huiying.properties.WeChatProperties;
import com.huiying.service.UserService;
import com.huiying.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: lsh
 * @Date: 2024/10/25/21:49
 * @Description:
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private WeChatProperties weChatProperties;

    @Autowired
    private UserMapper userMapper;

//    @Autowired
//    private LocalFileUtil fileUtil;

    @Autowired
    private FollowMapper followMapper;

    @Autowired
    private DemandMapper demandMapper;

    @Autowired
    private WorkMapper workMapper;

    //微信提供查询openid接口
    private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";



    /***
     * 用户登录与注册逻辑
     * @param code
     * @return: com.fx.entity.User
     */
    @Override
    public User login(String code) {
        String openId = getOpenId(code);

        //根据code查询openid，若为空则抛出登录失败的异常
        if (openId == null) {
            throw new RuntimeException(MessageConstant.USER_NOT_LOGIN);
        }
        log.info("{}",openId);

        User user = userMapper.getByOpenid(openId);

        //若用户不存在则将用户信息插入到用户表中
        if (user == null) {
//            //通过前端传来的微信头像地址获取图片
//            try {
//                byte[] bytes = HttpClientUtil.getUrl(userLoginDTO.getAvatar());
//                String objectName = UUID.randomUUID().toString() + ".jpg";
//                String newAvatar = aliOssUtil.upload(bytes, objectName);
//                userLoginDTO.setAvatar(newAvatar);
//            } catch (Exception e) {
//                throw new RuntimeException(MessageConstant.UPLOAD_FAILED);
//            }

            user = User.builder()
                    .openid(openId)
                    .build();

            userMapper.insertUser(user);
        }

        return user;
    }

    /***
     * 调用微信接口服务，获取用户的openid
     * @param code 前端传递
     * @return: java.lang.String
     */
    private String getOpenId(String code) {
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");

        String json = HttpClientUtil.doGet(WX_LOGIN, map);
        JSONObject jsonObject = JSON.parseObject(json);

        String openid = jsonObject.getString("openid");
        return openid;
    }

    /***
     * 根据id查询用户
     * @param id 用户id
     * @return: com.fx.entity.User
     */
    @Override
    public UserVO getById(Long id) {
        return userMapper.getById(id);
    }

    /**
     * 修改用户信息
     * @param userDTO
     * @return: void
     */
    @Override
    public void update(UserDTO userDTO) {
        Long userId = BaseContext.getCurrentId();
        userDTO.setId(userId);
        User user = new User();
        BeanUtils.copyProperties(userDTO,user);

        userMapper.update(user);

        // 2. 更新认证状态
        updateUserAuthentication(userId); // 更新该用户发布的需求单认证状态
    }

    /**
     * 关注用户
     * @param followeeId 被关注者id
     * @return: void
     */
    @Override
    public void follow(Long followeeId) {
        //从令牌中获取用户id
        Long userId = BaseContext.getCurrentId();
        Follow follow = Follow.builder()
                .userId(userId)
                .followeeId(followeeId)
                .createTime(LocalDateTime.now()).build();
        followMapper.insert(follow);
    }

    /**
     * 取消关注
     * @param followeeId 被关注者id
     * @return: void
     */
    @Override
    public void unfollow(Long followeeId) {
        //从令牌中获取用户id
        Long userId = BaseContext.getCurrentId();
        Follow follow = Follow.builder()
                .userId(userId)
                .followeeId(followeeId).build();
        followMapper.deleteByFolloweeId(follow);
    }

    /**
     *  获取关注列表
     * @return: java.util.List<com.fx.vo.FollowVO>
     */
    @Override
    public List<FollowVO> list() {
        //从令牌中获取用户id
        Long userId = BaseContext.getCurrentId();

        //根据用户id查询关注列表
        List<Long> List =  followMapper.list(userId);
        //根据关注的id查询列表
        List<FollowVO> followeeList = userMapper.getFollowBatch(List);

        return followeeList;
    }

    /**
     *  获取粉丝列表
     * @return: java.util.List<com.fx.vo.FollowVO>
     */
    @Transactional
    @Override
    public List<FollowVO> fansList() {
        //从令牌中获取用户id
        Long userId = BaseContext.getCurrentId();

        //根据用户id查询粉丝列表
        List<Long> List =  followMapper.getFansList(userId);
        List<FollowVO> fansList = userMapper.getFollowBatch(List);

        return fansList;
    }

    private void updateUserAuthentication(Long userId) {
        // 1. 获取用户信息，检查是否完成实名认证
        UserVO user = userMapper.getById(userId);

        // 2. 判断用户是否完成实名认证：即 name 和 id_number 是否都不为空
        String isAuthenticated = (user.getName() != null && user.getIdNumber() != null) ? "1" : "0";

        // 3. 更新用户发布的所有需求单的认证状态
        demandMapper.updateIsAuthenticatedByUserId(userId, isAuthenticated);
        workMapper.updateIsAuthenticatedByUserId(userId,isAuthenticated);
    }
}
